<html xmlns="https://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Language" content="zh-CN" />
<link href="style/css/manual-zip.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
<link href="style/css/manual-zip-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
<link href="style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" />
<title>suEXEC支持 － Apache 2.2 中文手册 [金步国]</title>
<script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?d286c55b63a3c54a1e43d10d4c203e75"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script>
</head>
<body id="manual-page">
<div id="page-header"><p class="menu"><a href="mod/index.html">模块索引</a> | <a href="mod/directives.html">指令索引</a> | <a href="faq/index.html">常见问题</a> | <a href="glossary.html">词汇表</a> | <a href="sitemap.html">站点导航</a></p><p class="apache">Apache HTTP Server 版本2.2</p><img alt="" src="images/feather.gif" /></div>
<div class="up"><a href="index.html"><img title="&lt;-" alt="&lt;-" src="images/left.gif" /></a></div>
<div id="path"><a href="https://www.apache.org/">Apache</a> &gt; <a href="https://httpd.apache.org/">HTTP Server</a> &gt; <a href="https://httpd.apache.org/docs/">文档</a> &gt; <a href="index.html">版本2.2</a></div>

<div id="translation-info">　　 <a href="translator_announcement.html#thanks">致谢</a> | 本篇译者：<a href="../../index.html">金步国</a>(<a href="../../index.html">作品集</a>) | 本页最后更新：2006年10月20日</div>
<div id="page-content"><div id="preamble"><h1>suEXEC支持</h1>


    <p><strong>suEXEC</strong>特性使得Apache可以使用与调用web服务器的用户<strong>不同</strong>的用户身份来运行<strong>CGI</strong>和<strong>SSI</strong>程序。而通常情况下，CGI或者SSI程序执行时使用和web服务器相同的用户身份。</p>

    <p>正确运用该特性，可以减少很多因为提供用户执行私有CGI或者SSI程序所带来的安全风险。但如果配置不当的话，则可能引起很多问题，使你的计算机产生更多的安全漏洞。如果你对管理 <em>setuid root</em> 程序以及可能导致的安全问题不熟悉的话，我们强烈建议你不要使用suEXEC。</p>
  </div>
	<div class="top"><a href="suexec.html#page-header"><img alt="top" src="images/up.gif" /></a></div>
<div class="section">
<h2><a name="before" id="before">开始之前</a></h2>

    <p>在我们开始切入正题之前，你必须明白Apache开发组以及本文档所做的假设。</p>

    <p>首先，我们假设你正在使用类UNIX操作系统，只有这类操作系统才具有<strong>setuid</strong>和<strong>setgid</strong>命令。所有的其他命令行的例子也是如此。其他的操作系统平台，即使也支持suEXEC，但是它的配置可能和我们所讲的并不相同。</p>

    <p>第二，我们假设你熟悉计算机的安全和管理计算机的一些基本概念。这关系到如何正确理解<strong>setuid/setgid</strong>操作以及对你的系统可能带来的各种影响和不同的安全等级。</p>

    <p>第三，我们假设你正在使用源代码<strong>未经修改的</strong>suEXEC版本。所有suEXEC的代码都经过开发者的仔细查验并做过大量测试。在这些代码中，人们采取了各种预防措施，使之简单、健壮、安全。修改这些代码可能会导致预料之外的问题和安全隐患。所以我们强烈地建议你<strong>不要修改</strong>代码，除非你精通安全编程，并愿意和Apache开发组共享成果。</p>

    <p>第四，也是最后一点，Apache开发组已经决定<strong>默认不安装</strong>suEXEC。suEXEC的配置需要管理员细致关注各个细节。在仔细考察过关于suEXEC的各种设置方法后，管理员应该使用标准的安装方法来安装suEXEC。设置的参数应该经过仔细推敲，以保证系统的安全运行。Apache开发组希望通过限制suEXEC的安装，仅使那些经过细致理解，并有能力运用它的管理员来使用。</p>

    <p>你还想使用suEXEC吗？还想？很好！那我们开始吧！</p>

</div><div class="top"><a href="suexec.html#page-header"><img alt="top" src="images/up.gif" /></a></div>
<div class="section">
<h2><a name="model" id="model">suEXEC的安全模型</a></h2>

    <p>在我们开始配置和安装suEXEC之前，我们需要先讨论一下它的安全模型。这样，你才能更好的理解suEXEC内部究竟做了些什么事情，以及哪些确保系统安全的预防措施。</p>

    <p><strong>suEXEC</strong>是基于一个setuid的"封装"程序，该程序由"主"Apache web服务器调用。当一个HTTP请求的是管理员指定的、以不同于"主"服务器用户身份运行的CGI或SSI程序时，该封装程序将被调用。处理这样的请求时，Apache将被请求的程序名及其UID和GID提供给suEXEC封装器。</p>

    <p>封装器(wrapper)通过处理下面所描述的步骤，来决定封装的成功或失败：如果有任意一个条件为假，程序将把错误情况记录到日志中，退出并返回错误信息。否则继续执行。(以下所说的"程序"均指"CGI/SSI程序")</p>

    <ol>
      <li>
        <strong>用户使用了合法的系统账号来执行封装程序了吗？</strong>
        <p class="indent">确保运行封装器的是一个系统中确实存在的用户。</p>
     </li>

     <li><strong>封装器被调用时，使用的参数个数正确吗？</strong> <strong></strong>
       	<p class="indent">封装器仅在使用了正确数量的参数调用时才会执行。Apache web服务器知道正确的参数格式是什么。如果封装器没有收到正确数量的参数，则说明要么被黑客攻击，要么Apache二进制代码中suEXEC的部分出了问题。</p>
      </li>

      <li>
        <strong>这个合法的用户被允许运行封装器吗？</strong>

        <p class="indent">这个用户是可以运行封装器的用户吗？仅有一个用户(Apache用户)被允许运行封装器。</p>
      </li>

      <li>
        <strong>目标CGI/SSI程序有不安全的分级路径索引吗？</strong>

        <p class="indent">目标CGI/SSI程序包含了"/"开头或者有".."后向路径索引吗？这些都是不允许的；并且目标程序必须位于suEXEC的文档根目录下。(参见下面的：<code>--with-suexec-docroot=<em>DIR</em></code>)</p>
      </li>

      <li>
        <strong>目标程序的所属用户名合法吗？</strong>

        <p class="indent">目标程序的所属用户名存在吗？</p>
      </li>

      <li>
        <strong>目标程序的所属用户组合法吗？</strong>

        <p class="indent">目标程序的所属用户组存在吗？</p>
      </li>

      <li>
        <strong>目标程序的所属用户名不是超级用户吗？</strong>
        <p class="indent">目前，suEXEC不允许root执行CGI/SSI程序。</p>
      </li>

      <li>
        <strong>目标程序所属用户的UID高于最小UID值吗？</strong>

        <p class="indent">最小UID值是在配置中指定的。你可以指定允许执行CGI/SSI程序的最小UID值，这样可以保证不会和系统账号冲突。</p>
      </li>

      <li>
        <strong>目标程序的所属用户组不是超级用户组吗？</strong>

        <p class="indent">目前，suEXEC不允许root组用户执行CGI/SSI程序。</p>
      </li>

      <li>
        <strong>目标程序所属用户组的GID高于最小GID值吗？</strong>

        <p class="indent">最小GID值是在配置中指定的。你可以指定允许执行CGI/SSI程序的最小GID值，这样可以保证不会和系统账号冲突。</p>
      </li>

      <li>
        <strong>封装器能够成功地变为目标用户和组吗？</strong>

        <p class="indent">这里就是程序变为目标用户和组的关键步骤了。我们是通过调用setuid和setgid来实现的。在组访问列表中，和该用户相关的所有组信息都将被初始化。</p>
      </li>

      <li>
        <strong>能够切换到程序所在的目录吗？</strong>

        <p class="indent">如果不存在，将无法包含程序文件。如果不能切换一般也表示目录不存在。</p>
      </li>

      <li>
        <strong>这个目录在Apache的网络空间中吗？</strong>

        <p class="indent">如果是对于服务器的一般请求，那么请求的目录是在suEXEC的根文档目录下吗？如果请求的是一个用户目录，那么该目录是在suEXEC配置的该用户的根目录下吗？(参见：<a href="suexec.html#install">suEXEC配置选项</a>)</p>
      </li>

      <li>
        <strong>该目录不具有其他用户可写的权限吗？</strong>

        <p class="indent">我们不想把目录开放给其他人；只有属主才可以改变该目录中的内容。</p>
      </li>

      <li>
        <strong>目标CGI/SSI程序存在吗？</strong>

        <p class="indent">如果不存在，当然无法继续运行。</p>
      </li>

      <li>
        <strong>目标CGI/SSI程序不可以被其他用户改写吗？</strong>

        <p class="indent">我们不想给其他人有修改程序的权限。</p>
      </li>

      <li>
        <strong>目标程序尚未被setuid或者setgid ？</strong>

        <p class="indent">我们不想要执行的程序被再次改变UID/GID。</p>
      </li>

      <li>
        <strong>目标用户和组与程序的用户和组相同吗？</strong>

        <p class="indent">用户是这个文件的属主吗？</p>
      </li>

      <li>
        <strong>我们可以成功清除进程的环境变量并保证操作的安全性吗？</strong>

        <p class="indent">suEXEC通过建立一个安全的可执行路径(在配置中定义)来清除该进程的环境变量，同时只传送在安全环境变量列表(配置中定义)中所列出的环境变量。</p>
      </li>

      <li>
        <strong>可以成功的变为目标程序并执行吗？</strong>

        <p class="indent">这里就是suEXEC结束，并开始运行目标程序的地方了。</p>
      </li>
    </ol>

    <p>这是suEXEC封装器标准操作方式的安全模型。它有些严格，并强加了CGI/SSI设计上的限制。但它是仔细考虑过安全之后一步步发展起来的模型。</p>

    <p>更多关于该安全模型如何根据服务器的配置来限制使用者的权限，以及恰当的suEXEC安装步骤能够避免的安全隐患，请参见<a href="suexec.html#jabberwock">警告和举例</a>部分。</p>
</div><div class="top"><a href="suexec.html#page-header"><img alt="top" src="images/up.gif" /></a></div>
<div class="section">
<h2><a name="install" id="install">配置和安装suEXEC</a></h2>
<p>继续我们的探险 ...</p>
    <p><strong>suEXEC配置选项</strong><br />
    </p>

    <dl>
      <dt><code>--enable-suexec</code></dt>

      <dd>该选项启用默认禁止的suEXEC功能。并同时至少提供一个 <code>--with-suexec-xxxxx</code> 选项，以使APACI使用suEXEC功能来处理请求。</dd>

      <dt><code>--with-suexec-bin=<em>PATH</em></code></dt>

      <dd>出于安全考虑，<code>suexec</code>二进制程序的路径必须用这个选项指定并硬编码在服务器里。比如：<code>--with-suexec-bin=/usr/sbin/suexec</code></dd>

      <dt><code>--with-suexec-caller=<em>UID</em></code></dt>

      <dd>Apache运行时所用的<a href="mod/mpm_common.html#user">UID</a>。这是唯一允许执行程序的用户。</dd>

      <dt><code>--with-suexec-userdir=<em>DIR</em></code></dt>

      <dd>定义suEXEC允许访问的用户宿主目录下的子目录。suEXEC将以用户身份执行这个目录下的所有可执行程序，所以这些程序必须是"安全程序"。如果使用"简单的"<code class="directive"><a href="mod/mod_userdir.html#userdir">UserDir</a></code>指令(即不带"*")，则此处应该被设置为相同的值。当<code class="directive"><a href="mod/mod_userdir.html#userdir">UserDir</a></code>指令所指向的目录与"passwd"文件所指定的用户宿主目录不同时，suEXEC将不会正常工作，其默认值是"public_html"。如果所支持的虚拟主机对每个用户有不同的<code class="directive"><a href="mod/mod_userdir.html#userdir">UserDir</a></code> ，则应该把他们集中在同一个父目录下，而用这个参数指向这个父目录。<strong>如果配置不当，"~userdir"下的cgi请求将无效！</strong></dd>

      <dt><code>--with-suexec-docroot=<em>DIR</em></code></dt>

      <dd>定义Apache的<code class="directive"><a href="mod/core.html#documentroot">DocumentRoot</a></code>。它是除<code class="directive"><a href="mod/mod_userdir.html#userdir">UserDir</a></code>外suEXEC唯一可以使用的目录。其默认目录是 <code>--datadir</code> 值所指定的带有"/htdocs"的后缀的目录，比如：如果配置了"<code>--datadir=/home/apache</code>"，那么"/home/apache/htdocs"目录将作为suEXEC处理器的文档根目录。</dd>

      <dt><code>--with-suexec-uidmin=<em>UID</em></code></dt>

      <dd>定义了suEXEC目标用户的最低UID。对大多数系统，一般是500或100。默认值是100</dd>

      <dt><code>--with-suexec-gidmin=<em>GID</em></code></dt>

      <dd>定义了suEXEC目标组的最低GID。对大多数系统，是100，默认值也是100。</dd>

      <dt><code>--with-suexec-logfile=<em>FILE</em></code></dt>

      <dd>它定义了suEXEC用于记录所做的事情以及发生的错误的日志文件名(对审核和排错很有用)，默认文件名是"suexec_log"，并位于标准的日志文件目录中(<code>--logfiledir</code>)。</dd>

      <dt><code>--with-suexec-safepath=<em>PATH</em></code></dt>

      <dd>定义传给CGI程序的一个安全的PATH环境变量的值。默认值是"/usr/local/bin:/usr/bin:/bin"</dd>
    </dl>

    <p><strong>编译和安装suEXEC处理器</strong><br />
     若用 <code>--enable-suexec</code> 打开了suEXEC功能，那么执行<code>make</code>命令时(Apache自带的)<code>suexec</code>二进制文件就会被自动建立。所有组件编译完毕后执行 <code>make install</code> 命令进行安装时，<code>suexec</code>文件将被安装在 <code>--sbindir</code> 选项指定的目录中，默认为"/usr/local/apache2/sbin/suexec"。<br />
    注意，安装过程需要<strong>root权限</strong>。为了使suEXEC处理器可以设置UID，其所有者必须为<code><em>root</em></code> ，并且文件模式中的执行位必须设置为1(允许执行)。</p>

    <p><strong>设置许可权限</strong><br />
    虽然suEXEC包装会检查以确保它的调用者就是<code class="program"><a href="programs/configure.html">配置选项</a></code> <code>--with-suexec-caller</code> 所指定的用户。但是总是存在这样的可能性：一个系统或者库在suEXEC执行用户身份检查之前调用它，这样就存在一个可利用的漏洞。通常，避免这种问题的最佳办法是，使用文件系的统权限来确保只有Apache组用户运行的程序才能执行suEXEC。</p>

    <p>如果你的web-server是按照如下所示进行配置的：</p>

    <div class="example"><p><code>
    User www<br />
    Group webgroup<br />
</code></p></div>

    <p>并且<code class="program"><a href="programs/suexec.html">suexec</a></code>被安装在"/usr/local/apache2/sbin/suexec"目录，你应当运行以下命令：</p>

    <div class="example"><p><code>
    chgrp webgroup /usr/local/apache2/bin/suexec<br />
    chmod 4750 /usr/local/apache2/bin/suexec<br />
</code></p></div>

    <p>这将确保只有Apache组用户运行的程序才能执行suEXEC。</p>
</div><div class="top"><a href="suexec.html#page-header"><img alt="top" src="images/up.gif" /></a></div>
<div class="section">
<h2><a name="enable" id="enable">启用和禁用suEXEC</a></h2>

    <p>Apache在启动过程中，会在 <code>--sbindir</code> 选项指定的目录(默认为："/usr/local/apache/sbin/suexec")中寻找<code class="program"><a href="programs/suexec.html">suexec</a></code>。如果Apache找到了一个正确配置的suEXEC处理器，会在错误日志中记录以下信息：</p>

<div class="example"><p><code>
    [notice] suEXEC mechanism enabled (wrapper: <var>/path/to/suexec</var>)
</code></p></div>

    <p>如果服务器启动后没有这个信息，那么很可能是服务器没找到适当的处理器，或者是这个执行程序没有安装<em>setuid root</em>。</p>

     <p>如果要在Apache服务器运行过程中打开suEXEC功能，则必须停止并重新启动Apache。用一个简单的HUP或USR1信号来重新启动是不够的。</p>
     <p>如果要关闭suEXEC功能，应该删除<code class="program"><a href="programs/suexec.html">suexec</a></code>文件，并停止和重新启动Apache。</p>
</div><div class="top"><a href="suexec.html#page-header"><img alt="top" src="images/up.gif" /></a></div>
<div class="section">
<h2><a name="usage" id="usage">使用suEXEC</a></h2>

    <p>对CGI程序的请求仅在下述两种情况下才会调用suEXEC包装：对一个含<code class="directive"><a href="mod/mod_suexec.html#suexecusergroup">SuexecUserGroup</a></code>指令的虚拟主机发起请求，或者该请求由<code class="module"><a href="mod/mod_userdir.html">mod_userdir</a></code>模块处理。</p>

    <p><strong>虚拟主机：</strong><br />使用suEXEC处理器的方法之一是在<code class="directive"><a href="mod/core.html#virtualhost">VirtualHost</a></code>定义中使用<code class="directive"><a href="mod/mod_suexec.html#suexecusergroup">SuexecUserGroup</a></code>指令。通过设置这个指令来确定不同于主服务器的UID，所有对CGI资源的请求将以<code class="directive"><a href="mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>所定义的<em>User</em>和<em>Group</em>身份执行。如果<code class="directive"><a href="mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>中没有这个指令，则将以主服务器的UID身份执行。</p>

    <p><strong>用户目录：</strong><br />
    由<code class="module"><a href="mod/mod_userdir.html">mod_userdir</a></code>处理的请求会调用suEXEC处理器以被请求的用户目录所属的UID执行CGI程序。此功能的唯一要求是，此用户必须有CGI执行权限，并且其脚本符合上述<a href="suexec.html#model">安全检查</a>的要求。参见 <code>--with-suexec-userdir</code> <a href="suexec.html#install">编译选项</a>。</p>
</div><div class="top"><a href="suexec.html#page-header"><img alt="top" src="images/up.gif" /></a></div>
<div class="section">
<h2><a name="debug" id="debug">调试suEXEC</a></h2>

    <p>如上所述，suEXEC处理器会在 <code>--with-suexec-logfile</code> 选项所指定的日志文件中记录信息。如果你感觉配置和安装不正常，可以查看这个日志以及服务器的错误日志。</p>

</div><div class="top"><a href="suexec.html#page-header"><img alt="top" src="images/up.gif" /></a></div>
<div class="section">
<h2><a name="jabberwock" id="jabberwock">谨防Jabberwock：警告和举例</a></h2>

    <p><strong>注意！</strong>这部分文档可能还没有完成。查看最新的修订版本，请到Apache开发组的<a href="https://httpd.apache.org/docs/2.2/suexec.html">在线文档</a>。</p>

    <p>以下是有关限制和服务器安装的几个注意事项，在提交任何关于suEXEC的"bugs"以前，请仔细阅读。</p>

    <ul>
      <li><strong>suEXEC注意事项</strong></li>

      <li>
        层次限制

        <p class="indent">出于安全和效率考虑，所有suEXEC请求必须被限制在虚拟主机或者用户目录的顶层。举例来说，如果你配置了4个虚拟主机，你必须把所有虚拟主机的文档根目录都安置在同一个主Apache目录中，这样才能为虚拟主机启用suEXEC。(例子以后会有的)</p>
      </li>

      <li>
        suEXEC的PATH环境变量

        <p class="indent">改变这个变量的值是危险的，必须确保其中每个路径都是<strong>可以信任</strong>的目录。你不会希望谁都可以在你的服务器上安装特洛伊木马。</p>
      </li>

      <li>
        改变suEXEC的代码

        <p class="indent">重申，如果你不清楚你在干什么就尽量避免，否则会带来<strong>大麻烦</strong>的。</p>
      </li>
    </ul>

</div></div>
<div id="footer">
<p class="apache">本文允许自由的转载、引用、再分发，但必须保留译者署名并注明出处；详见：<a href="translator_announcement.html#announcement">版权声明</a>。</p>
<p class="menu"><a href="mod/index.html">模块索引</a> | <a href="mod/directives.html">指令索引</a> | <a href="faq/index.html">常见问题</a> | <a href="glossary.html">词汇表</a> | <a href="sitemap.html">站点导航</a></p></div>
</body></html>
